package com.atguigu.lease.web.admin.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.atguigu.lease.common.constant.RedisConstant;
import com.atguigu.lease.common.utils.JwtUtil;
import com.atguigu.lease.model.entity.SystemUser;
import com.atguigu.lease.web.admin.globalhandexception.CommonException;
import com.atguigu.lease.web.admin.mapper.LoginMapper;
import com.atguigu.lease.web.admin.service.LoginService;
import com.atguigu.lease.web.admin.vo.login.CaptchaVo;
import com.atguigu.lease.web.admin.vo.login.LoginVo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wf.captcha.ArithmeticCaptcha;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;
@Slf4j
@Service
public class LoginServiceImpl extends ServiceImpl<LoginMapper, SystemUser> implements LoginService {
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private JwtUtil jwtUtil;

    /**
     * 获取验证码
     *
     * @return
     */
    @Override
    public CaptchaVo getCaptcha() {
//        //使用easyCaptcha生成数字+字母类型的验证码
//        SpecCaptcha captcha = new SpecCaptcha(130, 48, 5);
//        //设置生成验证码的类型 默认（数字+字母类型） 后续步骤也是获取验证码的答案，然后存到redis中
//        captcha.setCharType(SpecCaptcha.TYPE_DEFAULT);

        //使用easyCaptcha生成算数类型的验证码
        ArithmeticCaptcha captcha = new ArithmeticCaptcha(130, 48, 2);
        //获取验证码的答案
        String text = captcha.text();
        //为每一个用户设置一个唯一验证码的key
        String Key = RedisConstant.ADMIN_LOGIN_PREFIX + IdUtil.simpleUUID();
        //生成验证码的图片
        String base64 = captcha.toBase64();
        //将验证码的答案保存到redis中
        redisTemplate.opsForValue().set(Key, text, RedisConstant.ADMIN_LOGIN_CAPTCHA_TTL_SEC, TimeUnit.SECONDS);
        return new CaptchaVo(base64, Key);
    }


    /**
     * 登录
     *
     * @param loginVo
     * @return
     */
    @Override
    public String login(LoginVo loginVo) {
        //对loginVo进行校验
        if (StrUtil.isBlank(loginVo.getUsername())
                || StrUtil.isBlank(loginVo.getPassword())
                || StrUtil.isBlank(loginVo.getCaptchaKey())
                || StrUtil.isBlank(loginVo.getCaptchaCode())) {
            throw new CommonException("参数不能为空");
        }
        String password = loginVo.getPassword();
        //对密码进行Md5加密
        password = DigestUtil.md5Hex(password);
        //先查询数据库是否有该用户
        SystemUser one = this.lambdaQuery().eq(SystemUser::getUsername, loginVo.getUsername())
                .eq(SystemUser::getPassword, password)
                .one();
        if (one == null) {
            throw new CommonException("用户名或密码错误");
        }
        if (one.getStatus() == null || one.getStatus().getCode() == 0) {
            throw new CommonException("该用户已被禁用");
        }
        //查到了用户，再从redis中获取验证码
        String s = redisTemplate.opsForValue().get(loginVo.getCaptchaKey());

        //校验验证码
        if (StrUtil.isBlank(s) || !s.equals(loginVo.getCaptchaCode())) {
            throw new CommonException("验证码错误");
        }
        //验证码校验成功之后生成token
        String token = jwtUtil.createJwt(one.getId());
        if (StrUtil.isBlank(token)) {
            throw new CommonException("token生成失败");
        }
        //将token返回给前端
        log.info("登录成功，token为: {}", token);
        return token;
    }
}
